package com.glkj.vipsystem.modules.index.controller;

import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.glkj.vipsystem.common.utils.Constant;
import com.glkj.vipsystem.common.utils.R;
import com.glkj.vipsystem.entity.ao.OrderAO;
import com.glkj.vipsystem.entity.ao.VipCardAO;
import com.glkj.vipsystem.entity.ao.VipCardRecordAO;
import com.glkj.vipsystem.modules.sys.controller.AbstractController;
import com.glkj.vipsystem.modules.sys.entity.SysUserEntity;
import com.glkj.vipsystem.service.IOrderService;
import com.glkj.vipsystem.service.IVipCardRecordService;
import com.glkj.vipsystem.service.IVipCardService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * 首页数据统计控制器
 *
 * @author LiMuchan
 */
@RestController
@RequestMapping("/index/data")
public class IndexDataController extends AbstractController {

    @Resource
    private IOrderService orderService;
    @Resource
    private IVipCardService vipCardService;
    @Resource
    private IVipCardRecordService vipCardRecordService;

    /**
     * 列表
     */
    @RequestMapping(value = "")
    public R index() {
        Map<String, Object> data = new HashMap<>();
        SysUserEntity loginUser = getUser();
        String username = loginUser.getUsername();
        // 计算最近30天的数据
        Date now = new Date();
        Date thirtyDaysAgo = DateUtil.offset(now, DateField.DAY_OF_YEAR, -30);

        String start = DateUtil.formatDate(thirtyDaysAgo);
        String end = DateUtil.formatDate(now) + " 23:59:59";
        // 1.经计算新增会员数量
        int newVipCardNum = newVipCardNum(start, end);
        data.put("newVipCardNum", newVipCardNum);

        // 2.计算散客消费金额
        BigDecimal sankeAmount = consumeAmount(start, end, false);
        data.put("sankeAmount", sankeAmount);
        // 3.计算会员消费金额
        BigDecimal vipAmount = consumeAmount(start, end, true);
        data.put("vipAmount", vipAmount);

        // 4.计算会员新开卡和充值金额
        BigDecimal vipChargeAmount = vipChargeAmount(start, end);
        data.put("vipChargeAmount", vipChargeAmount);

        // 5.综合输入
        BigDecimal allAmount = allAmount(start, end);
        data.put("allAmount", allAmount);

        return R.ok().put("data", data);
    }

    private void setUserType(Wrapper<?> wrapper) {
        String username = getUser().getUsername();
        // 角色判断
        if (isCompanyRole()) {
            // 公司管理员
            wrapper.where("company_id = (select id from t_company where `username` = '" + username + "')");
        } else if (isEmployeeRole()) {
            wrapper.where("shop_id = (select shop_id from t_employee where `username` = '" + username + "')");
        }
    }

    private int newVipCardNum(String start, String end) {
        Wrapper<VipCardAO> vipWrapper = new EntityWrapper<>();
        if (StringUtils.isNoneBlank(start, end)) {
            vipWrapper.ge("create_time", start);
            vipWrapper.le("create_time", end);
        }
        setUserType(vipWrapper);
        return vipCardService.selectCount(vipWrapper);
    }

    /**
     * 计算消费金额
     *
     * @param start 开始时间
     * @param end   结束时间
     * @param vip   是否是计算vip的数据
     */
    private BigDecimal consumeAmount(String start, String end, boolean vip) {
        Wrapper<OrderAO> wrapper = new EntityWrapper<OrderAO>()
                .setSqlSelect("sum(order_amount) as amount")
                .between("create_time", start, end);
        if (vip) {
            wrapper.isNotNull("vip_card_id");
        } else {
            wrapper.isNull("vip_card_id");
        }
        setUserType(wrapper);
        Object obj = orderService.selectObj(
                wrapper
        );
        return obj == null ? BigDecimal.ZERO : (BigDecimal) obj;
    }

    /**
     * 计算会员新开及充续卡金额
     */
    private BigDecimal vipChargeAmount(String start, String end) {
        Wrapper<VipCardRecordAO> wrapper = new EntityWrapper<>();
        wrapper.setSqlSelect("sum(change_fee) as vipChargeAmount");
        wrapper.ne("change_type", Constant.VipCardRecordChangeType.COST.getValue());
        setUserType(wrapper);
        wrapper.between("create_time", start, end);
        Object obj = vipCardRecordService.selectObj(wrapper);
        return obj == null ? BigDecimal.ZERO : (BigDecimal) obj;
    }

    /**
     * 综合收入：会员开卡金额、会员充值续费金额、收银订单的实收金额
     *
     * @param start 开始时间
     * @param end   结束时间
     * @return 综合数据
     */
    private BigDecimal allAmount(String start, String end) {
        // 首先计算收银订单的实收金额
        Wrapper<OrderAO> orderWrapper = new EntityWrapper<>();
        orderWrapper.setSqlSelect("sum(pay_amount) as payAmount");
        orderWrapper.between("create_time", start, end);
        setUserType(orderWrapper);
        BigDecimal payAmount = (BigDecimal) orderService.selectObj(orderWrapper);
        payAmount = payAmount == null ? BigDecimal.ZERO : payAmount;

        // 计算会员开卡金额、会员充值续费金额
        Wrapper<VipCardRecordAO> vipWrapper = new EntityWrapper<>();
        vipWrapper.setSqlSelect("sum(change_fee) as vipAmount");
        vipWrapper.ne("change_type", Constant.VipCardRecordChangeType.COST.getValue());
        setUserType(vipWrapper);
        vipWrapper.between("create_time", start, end);
        BigDecimal vipAmount = (BigDecimal) vipCardRecordService.selectObj(vipWrapper);
        vipAmount = vipAmount == null ? BigDecimal.ZERO : vipAmount;

        return payAmount.add(vipAmount);
    }
}
